﻿#include "task.h"
/* 当前LED显示的状*/
uint32_t LedState = 0;
uint8_t displaydata[3] = {0, 0, 0};

uint8_t LedAddr[4] = {0x07,0x05, 0x03, 0x01}; // V1.1 版本硬件地址
uint8_t TubeAddr[3] = {0x0c, 0x0a, 0x08};
uint8_t PortTube[24] = {0xd7, 0x14, 0xcd, 0x5d, 0x1e, 0x5b, 0xdb, 0x15, 0xdf, 0x5f,/* 0 - 9 */
                        0xf7, 0x34, 0xed, 0x7d, 0x3e, 0x7b, 0xfb, 0x35, 0xff, 0x7f,/* 0. - 9. */
                        0x00, 0x01, 0x08, 0x40/* null - */};
/************************************
 * 数：AppDataToPhyData
 * 述：单字节按位翻转
 * 入：
 * AppData：应用层的数据接
 * 出：uint32_t
************************************/
byte reverseBinary(byte b)
{
    byte x = 0;
    for (int i = 0, p = 7; i < 8; i++, p -= 2)
    {
        x |= p > 0 ? (b & (1 << i)) << p : (b & (1 << i)) >> -p;
    }
    return x;
}
/************************************
 * 数：AppDataToPhyData
 * 述：应用层与物理层的数据转换
 * 入：
 * AppData：应用层的数据接
 * 出：uint32_t
************************************/
uint32_t AppDataToPhyData(uint32_t AppData) 
{
	union Data_union RES;
	for(uint8_t i = 0; i < 32; i++) 
	{
		if(AppData & (uint32_t)1 << i) 
		{
			RES.ut32bit |= (uint32_t)1 << ((i / 4) + (i % 4) * 8); 
		}
	}
    RES.byte_c[0] = reverseBinary(RES.byte_c[0]);
    RES.byte_c[1] = reverseBinary(RES.byte_c[1]);
    RES.byte_c[2] = reverseBinary(RES.byte_c[2]);
    RES.byte_c[3] = reverseBinary(RES.byte_c[3]);
	return RES.ut32bit;
} 
/************************************
 *数：Cls_LedOrTube
 *述：清除LED和tube显示内容
 * 入：void
 * 出：void
************************************/
void ClsLedOrTube(byte type) 
{
	if(type & CLS_LED)
	{
		LedState = 0;
		AIP1629_SendCmd(CMD_AIP1629_ADDFIXED);
		for(uint8_t i = 0; i < 4; i++) 
		{
			AIP1629_WriteByte(CMD_AIP1629_STARTADDR(LedAddr[i]), 0);
		} 
	}   
	if(type & CLS_TUBE)
	{
		memset(displaydata, 0, 3);
		AIP1629_SendCmd(CMD_AIP1629_ADDFIXED);
		for(uint8_t i = 0; i < 3; i++) 
		{
			AIP1629_WriteByte(CMD_AIP1629_STARTADDR(TubeAddr[i]), 0);
		}
	} 
	AIP1629_SendCmd(OFF);
}
/************************************
 * 数：ShowSingleLed
 * 述：点亮单个LED
 * 入：
 * id:0-31 
 * type:ON or OFF 
 * 出：void
************************************/ 
void ShowSingleLed(uint8_t id, uint8_t type) 
{
	if((id >= 0) && (id <= 31)) // 范围之内
	{
		id = 31-id;
		if(type == ON) 
		{
			LedState |= (uint32_t)1 << ((id / 4) + (id % 4) * 8); // 打开                
		}
		else if(type == OFF)
		{
			LedState &= (uint32_t)1 << ((id / 4) + (id % 4) * 8); // 关闭
		}
		AIP1629_SendCmd(CMD_AIP1629_ADDFIXED);// 固定地址模式
		AIP1629_SendCmd(THREE_LEVEL);              // 亮度
		for(uint8_t i = 0; i < 4; i++) {         // 发送数
			AIP1629_WriteByte(CMD_AIP1629_STARTADDR(LedAddr[i]), LedState>>(8*i));
		}
	}
}
/************************************
 * 数：ShowMultiLed
 * 述：同时点亮一组LED
 * 入：
 * id: 32位数据，每一位代表一个LED
 * 出：void
************************************/
void ShowMultiLed(uint32_t id) 
{
	//LedState = id;
	LedState = AppDataToPhyData(id);       // 打开对应的通道                  
	//Serial.println(LedState, BIN);
	AIP1629_SendCmd(CMD_AIP1629_ADDFIXED);// 固定地址模式
	AIP1629_SendCmd(THREE_LEVEL);              // 设置亮度
	for(uint8_t i = 0; i < 4; i++) {         // 发送数
	  AIP1629_WriteByte(CMD_AIP1629_STARTADDR(LedAddr[3-i]), LedState>>(8*i));
	} 
}

